﻿using Microsoft.Practices.Unity;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System;
using MiniStock.BusinessLogic.EventQueue.Data;
using MiniStock.BusinessLogic.EventQueue.Queue;
using MiniStock.Entities.Common;
using MiniStock.Entities.Common.Events;
using MiniStock.Entities.Stock.Events;
using MiniStock.Entities.Stock.Events.Customer;
using MiniStock.Infrastructure.Queue;

namespace MiniStock.BusinessLogic.EventDispatcher.Test
{
    
    
    /// <summary>
    ///This is a test class for EventHandlerLogicTest and is intended
    ///to contain all EventHandlerLogicTest Unit Tests
    ///</summary>
    [TestClass]
    public class EventHandlerLogicTest
    {

        public static IUnityContainer RootContainer;
        private TestContext testContextInstance;

        /// <summary>
        ///Gets or sets the test context which provides
        ///information about and functionality for the current test run.
        ///</summary>
        public TestContext TestContext
        {
            get
            {
                return testContextInstance;
            }
            set
            {
                testContextInstance = value;
            }
        }

        #region Additional test attributes
        // 
        //You can use the following additional attributes as you write your tests:
        //
        //Use ClassInitialize to run code before running the first test in the class
        [ClassInitialize()]
        public static void MyClassInitialize(TestContext testContext)
        {
            RootContainer = new UnityContainer();
            RootContainer.RegisterType<IEventQueue, DbTableQueue>();
        }
        
        //Use ClassCleanup to run code after all tests in a class have run
        //[ClassCleanup()]
        //public static void MyClassCleanup()
        //{
        //}
        //
        //Use TestInitialize to run code before running each test
        [TestInitialize()]
        public void MyTestInitialize()
        {
            SerializationHelper.KnownEventTypes.Clear();
            SerializationHelper.RegisterKnownEventTypes(new[] { typeof(CustomerEventBase) });
            EventBaseExtender.InitSerializer();
        }
        //
        //Use TestCleanup to run code after each test has run
        [TestCleanup()]
        public void MyTestCleanup()
        {
            using (var db = new EventDispatcherContext())
            {
                db.Database.ExecuteSqlCommand("delete from Events");
                db.Database.ExecuteSqlCommand("delete from ClientAffinity");
            }
        }
        //
        #endregion

        readonly Guid[] CustomerId = new[] {
            Guid.NewGuid(),
            Guid.NewGuid(),
            Guid.NewGuid(),
            Guid.NewGuid(),
        };

        readonly Guid[] EventId = new[] {
            Guid.NewGuid(),
            Guid.NewGuid(),
            Guid.NewGuid(),
            Guid.NewGuid(),
            Guid.NewGuid(),
            Guid.NewGuid(),
            Guid.NewGuid(),
            Guid.NewGuid(),
        };


        void SubmitEvents(EventDispatcherLogic sut)
        {
            sut.SubmitEvent(new CreateCustomerEvent { EventId = EventId[0], EventDate = DateTime.Now.AddMilliseconds(0), Id = CustomerId[0], Name="Teszt ügyfél 1"});
            sut.SubmitEvent(new ChangeCustomerNameEvent { EventId = EventId[1], EventDate = DateTime.Now.AddMilliseconds(1), Id = CustomerId[0], Name = "Demó ügyfél 1" });
            sut.SubmitEvent(new CreateCustomerEvent { EventId = EventId[2], EventDate = DateTime.Now.AddMilliseconds(2), Id = CustomerId[1], Name = "Demó ügyfél 2" });
            sut.SubmitEvent(new ChangeCustomerNameEvent { EventId = EventId[3], EventDate = DateTime.Now.AddMilliseconds(3), Id = CustomerId[0], Name = "Teszt ügyfél 1" });
            sut.SubmitEvent(new ChangeCustomerNameEvent { EventId = EventId[4], EventDate = DateTime.Now.AddMilliseconds(4), Id = CustomerId[1], Name = "Teszt ügyfél 2" });
        }

        ///// <summary>
        /////A test for GetEventForProcessing
        /////</summary>
        //[TestMethod()]
        //public void GetEventForProcessingTest()
        //{
        //    var sut = RootContainer.Resolve<EventDispatcherLogic>();
        //    SubmitEvents(sut);

        //    EventBase result;
        //    for (int i = 0; i < 5; i++)
        //    {
        //        result = sut.GetEventForProcessing("demo1");
        //        Assert.IsNotNull(result);
        //        Assert.AreEqual(EventId[i], result.EventId);
        //    }

        //    result = sut.GetEventForProcessing("demo1");
        //    Assert.IsNull(result);
        //}

        ///// <summary>
        /////A test for GetEventForProcessing
        /////</summary>
        //[TestMethod()]
        //public void GetEventForProcessingTest_Affinity()
        //{
        //    var sut = RootContainer.Resolve<EventDispatcherLogic>();
        //    SubmitEvents(sut);

        //    EventBase result;
        //    result = sut.GetEventForProcessing("demo1");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[0], result.EventId);

        //    result = sut.GetEventForProcessing("demo2");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[2], result.EventId);

        //    result = sut.GetEventForProcessing("demo3");
        //    Assert.IsNull(result);

        //    result = sut.GetEventForProcessing("demo2");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[4], result.EventId);

        //    result = sut.GetEventForProcessing("demo1");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[1], result.EventId);

        //    result = sut.GetEventForProcessing("demo1");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[3], result.EventId);
        //}

        ///// <summary>
        /////A test for GetEventForProcessing
        /////</summary>
        //[TestMethod()]
        //public void GetEventForProcessingTest_AffinityCleanup()
        //{
        //    var sut = RootContainer.Resolve<EventDispatcherLogic>();
        //    SubmitEvents(sut);

        //    EventBase result;
        //    result = sut.GetEventForProcessing("demo1");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[0], result.EventId);

        //    result = sut.GetEventForProcessing("demo2");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[2], result.EventId);

        //    result = sut.GetEventForProcessing("demo3");
        //    Assert.IsNull(result);
        //    sut.CleanupClient("demo1");

        //    result = sut.GetEventForProcessing("demo3");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[1], result.EventId);

        //    result = sut.GetEventForProcessing("demo1");
        //    Assert.IsNull(result);

        //    result = sut.GetEventForProcessing("demo2");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[4], result.EventId);

        //    result = sut.GetEventForProcessing("demo3");
        //    Assert.IsNotNull(result);
        //    Assert.AreEqual(EventId[3], result.EventId);
        //}
    }
}
